<?php

    class GoogleRedirects
    {
        private $redirects = array();

        public function __construct()
        {
            $this->Load();
        }

        /**
         * Gets url for redirect by Google query.
         *
         * @param string $url
         * @return string
         */
        public function GetRedirectUrl( $url )
        {
            if ( empty( $url ) )
                return "";

            if ( !$this->IsGoogleRedirect($url) )
                return "";

            $query = parse_url( $url, PHP_URL_QUERY );
            if ( empty( $query ) )
            {
                return "";
            }

            $queryKeyword = self::GetSearchKeyword( $query );

            return $this->GetRedirectUrlByKeyword($queryKeyword);
        }

        public function IsGoogleRedirect( $url )
        {
            $host = parse_url($url, PHP_URL_HOST);
            return ( strpos( $host, "google" ) !== false );
        }

        protected function GetRedirectUrlByKeyword($keyword)
        {
            if ( $keyword == null )
                return "";

            $redirectUrl = "";

            foreach ( $this->redirects as $url => $keywords )
            {
                if ( $this->CheckKeyword( $keywords, $keyword ) )
                {
                    $redirectUrl = $url;
                    break;
                }
            }

            return $redirectUrl;
        }

        /**
         * Compares page keywords with search engine keyword phrase.
         * Returns true if pageKeywords contains keyword phrase.
         *
         * @param string $pageKeywords
         * @param string $queryKeyword
         * @return bool Returns true if $queryKeyword exactly matches one of the
         *      phrase in the $pageKeywords
         *
         */
        protected function CheckKeyword( $pageKeywords, $queryKeyword )
        {
            $pageKeywords = explode( ",", $pageKeywords );
            if ( !empty( $pageKeywords ) )
            {
                $pageKeywords = array_map(array('self', 'NormalizeKeyword'), $pageKeywords);
            }

            $isValidPageKeywords = !empty( $pageKeywords );
            $isValidQueryKeyword = !empty( $queryKeyword );

            if ( !$isValidPageKeywords || !$isValidQueryKeyword )
                return false;

            $result = array_search( $queryKeyword, $pageKeywords ) !== false;

            return $result;
        }

        /**
         * Gets normalized search keyword from query string
         *
         * @param string $queryString
         * @return string Keyword phrase
         */
        protected static function GetSearchKeyword( $queryString )
        {
            $hasParameters = ( isset($queryString) && !empty($queryString) );
            if ( !$hasParameters )
                return null;

            preg_match( "/(([&])|(^))((q)|(as_q))=([^\&]+)/", $queryString, $valueQuery );
            $keywordIndex = 7;
            $keyword = "";
            if ( isset( $valueQuery ) && isset( $valueQuery[$keywordIndex] ) )
            {
                $keyword = $valueQuery[$keywordIndex];
            }

            return $keyword ? self::NormalizeKeyword($keyword) : '';
        }

        private static function NormalizeKeyword($keyword)
        {
            $keyword = urldecode( $keyword );
            $keyword = str_replace( '+', ' ', $keyword );
            $keyword = mb_strtolower( str_replace('/\s+/', ' ', trim($keyword)) );

            return $keyword;
        }
        
        /**
         * Gets data from google_redirects.xml
         *
         * @return array( "url" => "keywords" )
         */
        private function Load()
        {
            $cacheId = "redirects/google_redirects";
            $cache = Core::Cache();
            $this->redirects = $cache->Get($cacheId);

            if ( is_null($this->redirects) )
            {
                $xml = @file_get_contents( GOOGLE_REDIRECTS_FILE );
                $doc = Util::CreateXmlDocument($xml, true);
                $xpath = new XPathHelper( $doc );

                $this->redirects = array();
                $nodes = $xpath->GetNodes('/redirects/redirect[@keywords != "" and @url != ""]');
                foreach ( $nodes as $node )
                {
                    $keywords = $node->getAttribute("keywords");
                    $keywords = Core::Substitutions()->Process("$keywords");
                    $url   = $node->getAttribute("url");
                    $url   = Core::Substitutions()->Process("$url");
                    $this->redirects[$url] = $keywords;
                }
                $cache->Set($cacheId, $this->redirects);
            }
        }
    }

?>